package com.miyake.dsp.ui;

import com.miyake.dsp.OctaveFactory;
import com.miyake.dsp.OptimizedFactory;
import com.miyake.dsp.Processor;
import com.miyake.dsp.ProcessorFactory;
import com.miyake.dsp.ScilabFactory;
import com.miyake.dsp.circuit.RcSetting;
import com.miyake.dsp.circuit.ui.RcSettingUI;
import com.miyake.dsp.converter.AmplifierSetting;
import com.miyake.dsp.converter.Digitizer;
import com.miyake.dsp.converter.DigitizerSetting;
import com.miyake.dsp.converter.Invert;
import com.miyake.dsp.converter.InvertSetting;
import com.miyake.dsp.converter.LimiterImpl;
import com.miyake.dsp.converter.LimiterSetting;
import com.miyake.dsp.converter.Log;
import com.miyake.dsp.converter.LogSetting;
import com.miyake.dsp.converter.MovingAverageSetting;
import com.miyake.dsp.converter.NormalizeImpl;
import com.miyake.dsp.converter.OffsetSetting;
import com.miyake.dsp.converter.ui.AmplifierSettingUI;
import com.miyake.dsp.converter.ui.DigitizerSettingUI;
import com.miyake.dsp.converter.ui.LimiterSettingUI;
import com.miyake.dsp.converter.ui.LogSettingUI;
import com.miyake.dsp.converter.ui.MovingAverageUI;
import com.miyake.dsp.converter.ui.OffsetSettingUI;
import com.miyake.dsp.convolution.ConvolutionSetting;
import com.miyake.dsp.convolution.ui.ConvolutionSettingUI;
import com.miyake.dsp.filter.FilterSetting;
import com.miyake.dsp.filter.ui.FilterSettingPanel;
import com.miyake.dsp.generator.NoiseGenerator;
import com.miyake.dsp.generator.NoiseSetting;
import com.miyake.dsp.generator.PulseGenerator;
import com.miyake.dsp.generator.PulseSetting;
import com.miyake.dsp.generator.ui.NoiseSettingPanel;
import com.miyake.dsp.generator.ui.PulseSettingPanel;
import com.miyake.dsp.otdr.ui.OtdrSettingUI;
import com.miyake.dsp.otdr.ui.SpliceDetectorSettingUI;
import com.miyake.dsp.otdr.Otdr;
import com.miyake.dsp.otdr.OtdrSetting;
import com.miyake.dsp.otdr.SpliceDetector;
import com.miyake.dsp.otdr.SpliceDetectorSetting;
import com.miyake.dsp.ui.DspWidget.DspWidgetHandler;

public class DspCompositeUiFactory {
	public enum Engine {
		Scilab, Octave, Optimized
	}
	private ProcessorFactory factory;
	private double frequency;
	private Engine engine;
		
	public DspCompositeUiFactory(double frequency) {
		this.frequency = frequency;
		createFactory(Engine.Scilab);
	}

	public ProcessorFactory getFactory() {
		return factory;
	}


	public Engine getEngine() {
		return engine;
	}

	public void setEngine(Engine engine) {
		this.engine = engine;
		createFactory(engine);
	}

	public void setFactory(ProcessorFactory factory) {
		this.factory = factory;
	}


	public double getFrequency() {
		return frequency;
	}


	public void setFrequency(double frequency) {
		this.frequency = frequency;
	}


	private void createFactory(Engine engine) {
		if (engine.equals(Engine.Scilab)) {
			factory = new ScilabFactory(frequency);
		}
		else if (engine.equals(Engine.Octave)) {
			factory = new OctaveFactory(frequency);
		}
		else if (engine.equals(Engine.Optimized)) {
			factory = new OptimizedFactory(frequency);
		}
	}
	 
	
	public DspCompositeUI createNoiseGenerator(NoiseSetting setting) {
		return new DspCompositeUI(new NoiseGenerator(setting), new NoiseSettingPanel(setting));
	}
	
	public DspCompositeUI createPulseGenerator(PulseSetting setting) {
		setting.setFrequency(frequency);
		return new DspCompositeUI(new PulseGenerator(setting), new PulseSettingPanel(setting));
	}
	
	public DspCompositeUI createFilter(FilterSetting setting) {
		return new DspCompositeUI(factory.createFilter(setting), new FilterSettingPanel(setting));
	}
	
	public DspCompositeUI createFFT() {
		return new DspCompositeUI(factory.createFFT(), null);
	}
	
	public DspCompositeUI createDiff() {
		return new DspCompositeUI(factory.createDiff(), null);
	}
	
	public DspCompositeUI createOTDR(OtdrSetting setting) {
		setting.setFrequency(frequency);
//		OtdrSetting setting = new OtdrSetting(this.frequency, 1550, 10);
		return new DspCompositeUI(new Otdr(setting), new OtdrSettingUI(setting));
	}
	
	public DspCompositeUI createLog(LogSetting setting) {
		return new DspCompositeUI(new Log(setting), new LogSettingUI(setting));
	}
	
	public DspCompositeUI createConvolution(DspCompositeUI composite) {
		ConvolutionSetting setting = new ConvolutionSetting(composite.getComposite());
		ConvolutionSettingUI ui = new ConvolutionSettingUI(composite);
		Processor conv = factory.createConvolution(setting);
		final DspCompositeUI ret = new DspCompositeUI(conv, ui);
		ui.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				ret.run();
			}
		});
		
		return ret;
	}
	
	public DspCompositeUI createLimiter(LimiterSetting setting) {
		return new DspCompositeUI(new LimiterImpl(setting), new LimiterSettingUI(setting));
	}
	
	public DspCompositeUI createNormalize() {
		return new DspCompositeUI(new NormalizeImpl(), null);
	}
	
	public DspCompositeUI createAbsolute() {
		return new DspCompositeUI(factory.createAbsolute(), null);
	}
	
	public DspCompositeUI createOffset(OffsetSetting setting) {
		return new DspCompositeUI(factory.createOffset(setting), new OffsetSettingUI(setting));
	}
	
	public DspCompositeUI createRC(RcSetting setting) {
		return new DspCompositeUI(factory.createRc(setting), new RcSettingUI(setting));
	}
	
	public DspCompositeUI createInvert(InvertSetting setting) {
		return new DspCompositeUI(new Invert(setting), null);
	}
	
	public DspCompositeUI createMovingAverage(MovingAverageSetting setting) {
		return new DspCompositeUI(factory.createMovingAverage(setting), new MovingAverageUI(setting));
	}
	
	public DspCompositeUI createAmplifier(AmplifierSetting setting) {
		return new DspCompositeUI(factory.createAmplifier(setting), new AmplifierSettingUI(setting));
	}
	
	public DspCompositeUI createDigitizer(DigitizerSetting setting) {
		return new DspCompositeUI(new Digitizer(setting), new DigitizerSettingUI(setting));
	}
	
	public DspCompositeUI createSpliceDetector(SpliceDetectorSetting setting) {
		return new DspCompositeUI(new SpliceDetector(setting), new SpliceDetectorSettingUI(setting));
	}
}
